package tests;

import static org.junit.Assert.fail;

import org.junit.Test;

import src.Book;
import src.Borrowing;
import src.CD;
import src.Item;
import src.Library;
import src.Magazine;
import src.Map;
import src.UserAccount;
import src.Video;

public class TestAllClassesAvailable {

	private void testAvailability(InstanceConstructor constructor)
			throws Exception {
		try {
			constructor.createInstance();
		} catch (Exception e) {
			if (e instanceof ClassNotFoundException) {
				fail("The class " + constructor.getName() + " was not found!");
			} else {
				throw e;
			}
		}
	}

	@Test
	public void testLibraryAvailable() throws Exception {
		testAvailability(new LibraryInstanceConstructor());
	}

	@Test
	public void testUserAccountAvailable() throws Exception {
		testAvailability(new UserAccountInstanceConstructor());
	}

	@Test
	public void testItemsAvailable() throws Exception {
		testAvailability(new VideoInstanceConstructor());
		testAvailability(new BookInstanceConstructor());
		testAvailability(new MagazineInstanceConstructor());
		testAvailability(new MapInstanceConstructor());
	}

	@Test
	public void testBorrowingAvailable() throws Exception {
		testAvailability(new BorrowingInstanceConstructor());
	}
}

interface InstanceConstructor {
	public Object createInstance();

	public String getName();
}

class LibraryInstanceConstructor implements InstanceConstructor {

	public Object createInstance() {
		return Library.getTheLibrary();
	}

	public String getName() {
		return "Library";
	}

}

class UserAccountInstanceConstructor implements InstanceConstructor {

	public Object createInstance() {
		return new UserAccount("Some User", "1", "some.user@somewhere.com");
	}

	public String getName() {
		return "UserAccount";
	}

}

class VideoInstanceConstructor implements InstanceConstructor {

	public Object createInstance() {
		return new Video("author", "titel", "01.01.1978");
	}

	public String getName() {
		return "Video";
	}

}

class BookInstanceConstructor implements InstanceConstructor {

	public Object createInstance() {
		return new Book("author", "titel", "01.01.1978", "1234567890");
	}

	public String getName() {
		return "Book";
	}

}

class MagazineInstanceConstructor implements InstanceConstructor {

	public Object createInstance() {
		return new Magazine("author", "titel", "01.01.1978");
	}

	public String getName() {
		return "Magazine";
	}

}

class MapInstanceConstructor implements InstanceConstructor {

	public Object createInstance() {
		return new Map("author", "titel", "01.01.1978", "europe");
	}

	public String getName() {
		return "Map";
	}

}

class CDInstanceConstructor implements InstanceConstructor {

	public Object createInstance() {
		return new CD("author", "titel", "01.01.1978");
	}

	public String getName() {
		return "CD";
	}

}

class BorrowingInstanceConstructor implements InstanceConstructor {

	public Object createInstance() {
		return new Borrowing((Item) (new BookInstanceConstructor()
				.createInstance()),
				(UserAccount) (new UserAccountInstanceConstructor()
						.createInstance()));
	}

	public String getName() {
		return "Borrowing";
	}

}